package gao.xiaolei.service;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import gao.xiaolei.dao.*;
import gao.xiaolei.entity.*;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import gao.xiaolei.util.RedisUtil;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service("UrlService")
public class UrlService {

    @Resource(name = "UrlDao")
    private UrlDao urlDao;

    @Resource(name = "UrlRoleDao")
    private UrlRoleDao urlRoleDao;

    @Resource(name = "UserRoleDao")
    private UserRoleDao userRoleDao;

    @Resource(name = "RoleDao")
    private RoleDao roleDao;

    @Resource(name = "UserDao")
    private UserDao userDao;

    @Resource(name = "AuthVersionDao")
    private AuthVersionDao authVersionDao;

    @Resource(name = "RedisUtil")
    private RedisUtil redis;

    @Transactional
    public void updateUrl(String id, String url, String detial, int readOnly) {
        // 判断是否是新添加的权限
        Optional<Url> opUrl = urlDao.findById(id);
        if (!opUrl.isPresent())
            urlDao.save(new Url(id, url, detial, readOnly));
        else {
            boolean flag = false;
            Url oldUrl = opUrl.get();
            if (!oldUrl.getUrl().equals(url)
                    || !oldUrl.getUrlDetial().equals(detial) || !oldUrl.getReadOnly().equals(readOnly)) {
                if (!oldUrl.getUrl().equals(url) || !oldUrl.getReadOnly().equals(readOnly)) {
                    flag = true;
                    oldUrl.setUrl(url);
                    oldUrl.setReadOnly(readOnly);
                }
                if (!oldUrl.getUrlDetial().equals(detial))
                    oldUrl.setUrlDetial(detial);
                urlDao.save(oldUrl);
                if (flag) {//更改了权限就要将拥有这些权限的用户的权限版本号更新
                    List<String> roleIds = urlRoleDao.queryRoleByUrlId(id);
                    List<String> userId = userRoleDao.getUserByRoleIdIn(roleIds);
                    userId = userId.stream().distinct().collect(Collectors.toList());//因为查出来的可能有重复的用户,所以要去重
                    List<User> users = userDao.findAllById(userId);
                    for (int i = 0, length = users.size(); i < length; i++) {
                        AuthVersion av = authVersionDao.findById(users.get(i).getId()).orElse(new AuthVersion(users.get(i).getId(), 0));
                        av.setVersion(av.getVersion() + 1);
                        authVersionDao.save(av);
                        redis.set(users.get(i).getId(), av.getVersion(), redis.EXPIRETIME);
                    }
                }
            }
        }
    }

    @Transactional
    public void deleteUrl(String urlJson) {
        JsonArray delUrls = new JsonParser().parse(urlJson).getAsJsonArray();
        for (JsonElement delUrl : delUrls) {
            String id = delUrl.getAsString();
            if(urlDao.existsById(id)){//如果数据库存在才去删除
                List<String> roleIds=urlRoleDao.queryRoleByUrlId(id);
                urlRoleDao.deleteByUrlId(id);
                urlDao.deleteById(id);
                //删除了权限就要将拥有这些权限的用户的权限版本号更新
                if (roleIds.size() != 0) {
                    List<String> userId = userRoleDao.getUserByRoleIdIn(roleIds);
                    userId = userId.stream().distinct().collect(Collectors.toList());//因为查出来的可能有重复的用户,所以要去重
                    List<User> users = userDao.findAllById(userId);
                    for (int i = 0, length = users.size(); i < length; i++) {
                        AuthVersion av = authVersionDao.findById(users.get(i).getId()).orElse(new AuthVersion(users.get(i).getId(), 0));
                        av.setVersion(av.getVersion() + 1);
                        authVersionDao.save(av);
                        redis.set(users.get(i).getId(), av.getVersion(), redis.EXPIRETIME);
                    }
                }
            }
        }
    }

    public List<Url> getAll() {
        return urlDao.findAll();
    }
}
